package de.unistuttgart.iaas.interaction.mail.services;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.sql.*;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Properties;

import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.internet.AddressException;

import org.apache.log4j.*;

import com.eaio.uuid.UUID;

import de.unistuttgart.iaas.interaction.mail.AdminConnector;
import de.unistuttgart.iaas.interaction.mail.database.MySQLAccess;
import de.unistuttgart.iaas.interaction.mail.util.CommonTools;
import de.unistuttgart.iaas.interaction.mail.util.ConfigFileHandler;
import de.unistuttgart.iaas.interaction.mail.util.ErrorHandler;


import de.unistuttgart.iaas.interaction.mail.util.LoggingFileHandler;

import de.unistuttgart.iaas.interaction.mail.util.TimeoutComputer;
/**
 * This class get a Request from a process.
 * @author Lina Sun
 *
 */
public class GetRequest 
{
	
//	private static String success = "Your request have been accepted and will be done.";
	private static String fail= "Sorry! Your request cann't be accepted.\n";
	private static String reason_dbconn= "Database Connection Error.\n";
	private static String reason_parameter = "Invalid inputparameter.\n";
	private static String reason_sql= "SQL Error.\n";
	private static String no_register = "This Address isn't registered. Please send a email to us. Thanks\n";
	private static String configurationData = "C:\\CommunicationService\\configuration.conf";
	private static Logger logger = Logger.getLogger(GetRequest.class);
	
	/**
	 * This method gets a request from a process, stores this request in the database.
	 * @param recipient
	 * @param subject
	 * @param message
	 * @param attachments
	 * @param timeout
	 * @param response
	 * @param responseTemplate
	 * @return
	 * @throws AddressException
	 * @throws MessagingException
	 */
//	public static String getRequest(String recipient, String subject, 
//					String message,String attachments, String timeout,String response,
//					responseTemplate responseTemplate) throws AddressException, MessagingException
	public static String getRequest(String recipient, String subject, 
							String message,String attachments, String timeout,String response,
							String responseTemplate) throws AddressException, MessagingException
{
		boolean parameterFlag = true;
		String[] attachmentList = null;
    	Connection conn = null;
		UUID u = new UUID();
		Calendar cal = Calendar.getInstance();
		DateFormat df=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  			
		String sentTime = df.format(cal.getTime());
		String newtime="";
		TimeoutComputer tom = new TimeoutComputer();
		String responseTemplateString = "";
		
		ConfigFileHandler config = new ConfigFileHandler(configurationData);
		LoggingFileHandler logFileHandler = new LoggingFileHandler(configurationData);
		MySQLAccess dao = new MySQLAccess();
		String table_sentmails = config.getTable_sentmails();
		String table_attachments = config.getTable_mailattachments();
				
		Properties properties = new Properties();
		properties.setProperty("log4j.rootLogger", logFileHandler.getMailLogLevel()+", R");
		properties.setProperty("log4j.appender.R", logFileHandler.getMailAppender());
		properties.setProperty("log4j.appender.R.File", logFileHandler.getGetRequestLogFilePath());
		properties.setProperty("log4j.appender.R.MaxFileSize", logFileHandler.getMailLogFileSize() );
		properties.setProperty("log4j.appender.R.MaxBackupIndex", logFileHandler.getMailMaxBackupIndex());
		properties.setProperty("log4j.appender.R.layout", logFileHandler.getMailLayout());
		properties.setProperty("log4j.appender.R.layout.ConversionPattern", logFileHandler.getMailPattern());
		PropertyConfigurator.configure( properties );
		
		logger.info("---------------------GetRequest----------------------");
		
		if(recipient.equals("")||recipient.equals(" ")||recipient.equals(null))
		{
			parameterFlag = false;
			fail = "Invalid recipient. " + fail;
		}
		if(subject.equals("")||subject.equals(" ")||subject.equals(null))
		{
			parameterFlag = false;
			fail = "False subject. " + fail;
		}
		if(message.equals("")||message.equals(" ")||message.equals(null))
		{
			parameterFlag = false;
			fail = "False messagebody. " + fail;
		}
		if(timeout!=null&&!timeout.equals("0")&&!timeout.equals(""))
 		{
			if(timeout.split(":").length==4)
			{
				for(int i=0; i<timeout.split(":").length;i++)
				{
					String[] temp=timeout.split(":");
					try{
						
						Integer.parseInt(temp[i] );
						
					}catch (NumberFormatException e)
					{
						parameterFlag = false;
						fail = "False timeout. " + fail;
					}					
				}
				newtime= tom.setTimeOut(timeout); 
			}else{
				
				parameterFlag = false;
				fail = "False timeout. " + fail;
				}
 		}else{
 				newtime= null;
 		}
		
//		if(!attachments.equals("")&&attachments!= null)
// 	    {
// 	    	attachmentList = attachments.split(";");
// 		    for(int i = 0; i< attachmentList.length; i++)
// 			{	
// 		    	try{
//					 InputStream fin = new FileInputStream(new File(attachmentList[i]));
//
// 		    	}catch(FileNotFoundException e)
//				{
// 		    		parameterFlag = false;
// 		    		fail = "False attachments. " + fail;
//				}
// 			}
// 	    }
		if(response.equals(""))
		{
			parameterFlag =false;
			fail = " Response parameter can not be empty. " + fail;
			
		}else{
			
			if(response.equalsIgnoreCase("yes"))
			{
				if(responseTemplate==null||responseTemplate.equals(""))
				{
					parameterFlag =false;
					fail = "responseTemplate parameter can not be empty. " + fail;
				}else
				{
					responseTemplate=responseTemplate.replaceAll("&lt;", "<");
					responseTemplate=responseTemplate.replaceAll("&gt;", ">");
					responseTemplate=responseTemplate.replaceAll("&amp;", "&");
					responseTemplateString = CommonTools.getResponseTemplate(responseTemplate, config);
					if(responseTemplateString.equalsIgnoreCase("wsResponseTempError"))
					{
						parameterFlag = false;
						fail = responseTemplateString+"."+fail;
					}
					
				}
//				if(responseTemplate==null)
//				{
//					parameterFlag =false;
//					fail = "responseTemplate parameter can not be empty. " + fail;
//				}else
//				{
//					responseTemplateString = CommonTools.getResponseTemplate(responseTemplate);
//
//					if(responseTemplateString.equalsIgnoreCase("wsResponseTempError"))
//					{
//						parameterFlag = false;
//						fail = responseTemplateString+"."+fail;
//					}
//					
//				}
			}else if(response.equalsIgnoreCase("no"))
			{
				
			}else
			{
				parameterFlag =false;
				fail = "False response. " + fail;
			}
		}

		if( parameterFlag ==false)
		{
			logger.error(reason_parameter+fail);
			System.out.println(reason_parameter+fail);
			return "ERROR";
			
		}
		
    	 
    	 try
    	 {
	    		conn = dao.connDataBase(config);
	    	
	    		if(conn != null)
	    		{	    		 
	    			Statement reg_statement = conn.createStatement();
	    			ResultSet rs = reg_statement.executeQuery("select * from maildb."+ config.getTable_mailregister()+" where mailaddress='"+recipient+"'");
	    			if(rs.next())
	    			{
			 			PreparedStatement preStatement = conn.prepareStatement("insert into maildb."+ table_sentmails +" values(?,?,?,?,?,?,?,?,?,'Request',?)");
			 						
			 			preStatement.setString(1, u.toString());
			 			preStatement.setString(2, recipient);
			 			preStatement.setString(3, config.getMailAddress());
			 			preStatement.setString(4, subject);
			 			preStatement.setString(5, message);
			 			preStatement.setString(6, sentTime);
			 			preStatement.setString(7, response);
			 			preStatement.setString(8, responseTemplateString );		 			
			 			preStatement.setString(9, newtime);
			 			preStatement.setString(10, "NEW");
			 			preStatement.executeUpdate();
			 			preStatement.close();
		 			
		 			
			 	    	if(!attachments.equals("")&&attachments!= null)
			 	    	{
			 				try {
			 		            InputStream fin = new ByteArrayInputStream(attachments.getBytes("UTF-8"));
			 		            String filename = u.toString()+".txt";
			 		            PreparedStatement preStatementAtt = conn.prepareStatement("insert into maildb."+ table_attachments +"(mail_id,filename,content) values(?,?,?)");
			 		            
			 		           preStatementAtt.setString(1, u.toString());
			 		          preStatementAtt.setString(2,filename);
			 		           preStatementAtt.setBlob(3, fin);
			 		           preStatementAtt.executeUpdate();
			 		           preStatementAtt.close();
			 		        } catch (UnsupportedEncodingException e) {
			 		            e.printStackTrace();
			 		        }
//			 	    		attachmentList = attachments.split(";");
//			 		    	for(int i = 0; i< attachmentList.length; i++)
//			 				{	 
//			 		    		String filename="";
//			 		    		try{
//			 					 PreparedStatement preStatementAtt = conn.prepareStatement("insert into maildb."+ table_attachments +"(mail_id,filename,content) values(?,?,?)");
//			 					 preStatementAtt.setString(1, u.toString());
//			 					 int index = attachmentList[i].lastIndexOf("\\");
//			 					 filename = attachmentList[i].substring(index+1);
//			 					 preStatementAtt.setString(2,filename);					 
//			 					 InputStream fin = new FileInputStream(new File(attachmentList[i]));
//			 					 preStatementAtt.setBlob(3, fin);
//			 					 preStatementAtt.executeUpdate();
//			 					 preStatementAtt.close();
//			 					 
//			 					 }catch(FileNotFoundException e)
//			 					 {
//			 						 logger.error("The attachment("+filename+") in the Request to "+recipient+ "can not be found.");
//			 						 System.out.println("file not found");
//			 					 }
//			 					 
//			 				}
			 	    	}	
			 	    	logger.info("Request is accepted:\n to: "+ recipient+"\n subject: "+subject+"\n message: "+message+"\n response: "+ response+"\n attachments: "+attachments);
			 	    	if(response.equalsIgnoreCase("yes"))
			 	    	{
			 	    		return u.toString();
			 	    	}else
			 	    	{
			 	    		return "The request is accepted.";
			 	    	}
			 	    	
	    			}else
	    			{
			 			PreparedStatement preStatement = conn.prepareStatement("insert into maildb."+ table_sentmails +" values(?,?,?,?,?,?,?,?,?,'Request',?)");
 						
			 			preStatement.setString(1, u.toString());
			 			preStatement.setString(2, recipient);
			 			preStatement.setString(3, config.getMailAddress());
			 			preStatement.setString(4, "Please register for mail service!");
			 			preStatement.setString(5, "you are invalid user. Please answer this mail for register.");
			 			preStatement.setString(6, sentTime);
			 			preStatement.setString(7, "no");
			 			preStatement.setString(8, "");		 			
			 			preStatement.setString(9, newtime);
			 			preStatement.setString(10, "NEW");
			 			preStatement.executeUpdate();
			 			preStatement.close();

			 			logger.error("This Address isn't registered: "+recipient);
			 			System.out.println(no_register + "Our mailaddress: "+config.getMailAddress());
			 			return "ERROR";
//						return no_register + "Our mailaddress: "+config.getMailAddress();
	    			}
	 	    	
    		 }else
    		 {
    			 logger.error(reason_dbconn+fail);
    			 return "ERROR";
//    			 return reason_dbconn+fail;
    		 }
    		 
    	 }catch(SQLException e)
    	 {
    		 logger.error(reason_sql+fail);
    		 System.out.println(reason_sql+fail);
			 Session session = AdminConnector.SendConnector(config);
			 ErrorHandler.sendErrorMessageForSQL(session, config, e);
			 return "ERROR";
//    		 return reason_sql+fail;
    		 //errorHandler
    		 
    	 }catch(Exception e)
    	 {
    		 logger.error(fail);
    		 e.printStackTrace();
    		 System.out.println(fail);
			 Session session = AdminConnector.SendConnector(config);
			 ErrorHandler.sendErrorMessageForGetRequest(session, config, e);
			 return "ERROR";
//    		 return fail;
    	 }
		
	}

}
